home *** CD-ROM | disk | FTP | other *** search
- /*++
- /* NAME
- /* ktrans 3
- /* SUMMARY
- /* k-protocol strategy routines
- /* PACKAGE
- /* uucp across the TUEnet
- /* SYNOPSIS
- /* #include "kp.h"
- /*
- /* krproto(fd,data,size)
- /* int fd, *size;
- /* char data[MAXPACKSIZ];
- /*
- /* kwproto(fd,data,size)
- /* int fd, size;
- /* char data[MAXPACKSIZ];
- /*
- /* kclsproto(fd)
- /* int fd;
- /* DESCRIPTION
- /* The functions in this file take care of handshake and error
- /* detection/recovery. The read/write functions return through an
- /* external function kfail() in case of fatal errors, or protocol
- /* termination by the network partner.
- /*
- /* The following packet types are used:
- /*
- /* .nf
- /* .in +5
- /* D packets contain data.
- /* Y packets are sent when a correct data packet was received.
- /* N packets are sent when incorrect data was received.
- /* A packets are sent to shut down the k protocol.
- /* .fi
- /*
- /* Krproto() sends the data and either returns normally, or through
- /* kfail().
- /*
- /* Kwproto() returns the received data or returns through kfail().
- /*
- /* Kclsproto() sends the protocol termination sequence to the other
- /* side, either to signal the end of transfers, or to confirm
- /* reception of an end-of-protocol sequence.
- /*
- /* The strategy for sending data is as follows:
- /*
- /* Send packet.
- /* If (ACK for last packet) or (NAK for next packet) received, terminate.
- /* If (NAK for last packet) or no response received, retransmit.
- /* If data received with previous packet nr, ignore and wait for NAK.
- /* If data received with next packet nr, NAK that data and terminate.
- /* Otherwise (bad packet number, unexpected packet type) abort.
- /*
- /* The strategy for receiving data is complementary:
- /*
- /* Wait for packet
- /* If expected packet received, ACK it and terminate.
- /* If previous data packet received, ACK it and wait for next packet.
- /* If bad packet received, send NAK for expected packet.
- /* If nothing received, wait for another packet.
- /* Otherwise (bad packet number, unexpected packet type) abort.
- /* FUNCTIONS AND MACROS
- /* kspack, krpack, kfail
- /* AUTHOR(S)
- /* Wietse Venema
- /* Eindhoven University of Technology
- /* Department of Mathematics and Computer Science
- /* Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands
- /* CREATION DATE
- /* Mon Feb 3 13:12:08 MET 1986
- /* LAST MODIFICATION
- /* 90/01/22 13:01:59
- /* VERSION/RELEASE
- /* 2.1
- /*--*/
-
- #include "kp.h"
-
- static char recpkt[MAXPACKSIZ]; /* receive packet buffer */
- static int n = 0; /* packet number */
-
- kwproto( fd, packet, size)
- int fd;
- char *packet;
- int size;
- {
- int num, numtry; /* Packet number, tries */
- int len;
-
- kspack(fd, 'D',n,size,packet); /* Send a D packet */
-
- for (numtry = 0; numtry < MAXTRY; numtry++) {
- switch(krpack(fd,&num,&len,recpkt)) /* What was the reply? */
- {
- case 'D': /* DATA */
- if ((num+1)%64 == n) { /* Previous packet ? */
- numtry = 0; /* Reset counter */
- break; /* Don't ack it; read again */
- } else if (num != (n+1)%64) /* Fatal error, unless it */
- kfail(); /* carries next packet number */
- kspack(fd,'N',num,0,NULLP); /* Can't use data now */
-
- case 'N': /* NAK */
- if (n == num) { /* Send another one, */
- kspack(fd, 'D',n,size,packet);
- break;
- }
- num = (--num<0 ? 63:num); /* unless NAK for next packet */
-
- case 'Y': /* ACK */
- if (n != num) kfail(); /* If wrong ACK, fail */
- n = (n+1)%64; /* Bump packet count */
- return;
-
- case TIME: /* No response */
- case FAIL: /* Bad packet */
- kspack(fd, 'D',n,size,packet);
- break; /* Send data packet again */
-
- default:
- kfail(); /* Something else, abort */
- }
- }
- kfail(); /* Too may retries, abort */
- }
-
- krproto( fd, packet, size)
- int fd;
- char *packet;
- int *size;
- {
- int num, numtry; /* Packet number, tries */
-
- for (numtry = 0; numtry < MAXTRY; numtry++)
- {
- switch (krpack(fd,&num,size,packet)) /* Get packet */
- {
- case 'D':
- if (num == n) { /* Right packet? */
- kspack(fd,'Y',n,0,NULLP); /* Acknowledge the packet */
- n = (n+1)%64; /* Bump packet number, mod 64 */
- return;
- } else if (num == ((n==0) ? 63:n-1)) { /* Previous packet? */
- kspack(fd,'Y',num,0,NULLP); /* Re-ack previous packet */
- numtry = 0; /* Reset counter */
- break; /* Read another packet */
- } else
- kfail(); /* Sorry, wrong number */
-
- case TIME: /* No packet */
- break; /* Don't NAK */
-
- case FAIL: /* Bad packet */
- kspack(fd,'N',n,0,NULLP); /* Return a NAK */
- break; /* Read another packet */
-
- default:
- kfail(); /* Something else, abort */
- }
- }
- kfail(); /* Too may retries, abort */
- }
-
- kclsproto( fd)
- int fd;
- {
- kspack( fd, 'A', 0, 0, NULLP); /* Send an 'A' packet */
- kspack( fd, 'A', 0, 0, NULLP); /* and another two since */
- kspack( fd, 'A', 0, 0, NULLP); /* we won't get ACKs */
- return 0;
- }
-